package com.seuic.hnjiningposapp.hnapps.util;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.DeviceUtils;
import com.blankj.utilcode.util.EncryptUtils;
import com.blankj.utilcode.util.MapUtils;
import com.blankj.utilcode.util.NetworkUtils;
import com.blankj.utilcode.util.SPStaticUtils;
import com.blankj.utilcode.util.TimeUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.blankj.utilcode.util.Utils;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.callback.AbsCallback;
import com.lzy.okgo.callback.StringCallback;
import com.lzy.okgo.model.Response;
import com.seuic.posdsdk.pos_func.PosFuncs;
import com.socks.library.KLog;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Date;

import java.io.UnsupportedEncodingException;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Random;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.BufferedSink;

/**
 * @author rainking
 */
public class HttpUtils {
    private static final String TAG = HttpUtils.class.getName();

    private static final int KEY_RANDOM = 13;


    /**
     * 网络统一返回
     */
    public interface BaseApiListener {
        /**
         * 数据返回
         *
         * @param data 数据
         */
        void onSuccess(String data);

        /**
         * 错误提醒
         *
         * @param msg
         */
        void onError(String msg);
    }

    /**
     * 读卡统一返回
     */
    public interface BaseReadCardListener {
        /**
         * 数据返回
         *
         * @param data 数据
         */
        void onSuccess(String data, String track2Data);

        /**
         * 错误提醒
         *
         * @param msg
         */
        void onError(String msg);
    }

    public interface BaseReadCardTwListener {
        /**
         * 数据返回
         *
         * @param data 数据
         */
        void onSuccess(String data, String track2Data, String pw);

        /**
         * 错误提醒
         *
         * @param msg
         */
        void onError(String msg);
    }


    /**
     * post请求
     *
     * @param context         上下文
     * @param json            数据
     * @param baseApiListener 接口回调函数
     */
    public static void postByOkGo(Context context, String json, BaseApiListener baseApiListener) {
        if (NetworkUtils.isConnected()) {
            if (!TextUtils.isEmpty(json)) {
                KLog.json(json);
                OkGo.<String>post(Api.BASE_URL)
                        .tag(context)
                        .upRequestBody(RequestBody.create(MediaType.parse("application/json;charset=GB18030"), json))
                        .execute(new AbsCallback<String>() {
                            @Override
                            public void onSuccess(Response<String> response) {
                                if (baseApiListener != null) {
                                    JSONObject jsonObject = JSON.parseObject(response.body());
                                    String body = JSON.toJSONString(jsonObject);
                                    KLog.e(body);
                                    KLog.json(body);
                                    baseApiListener.onSuccess(body);
                                }
                            }

                            @Override
                            public String convertResponse(okhttp3.Response response) throws Throwable {
                                return gB18030ByteArrayToUtf8String(Objects.requireNonNull(response.body()).bytes());
                            }

                            @Override
                            public void onError(Response<String> response) {
                                super.onError(response);
                                if (baseApiListener != null) {
                                    baseApiListener.onError("服务器异常,请联系维护人员！");
                                }
                            }
                        });
            } else {
                if (baseApiListener != null) {
                    baseApiListener.onError("上报参数错误，请检查输入参数！");
                }
            }
        } else {
            if (baseApiListener != null) {
                baseApiListener.onError("设备已经断网，请检查网络环境！");
            }
        }
    }


    private static String gB18030ByteArrayToUtf8String(byte[] bytes) {
        ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
        CharBuffer gb18030 = Charset.forName("GB18030").decode(byteBuffer);
        ByteBuffer utf8 = StandardCharsets.UTF_8.encode(gb18030);
        return new String(utf8.array());
    }


    /**
     * @param transServiceCode 交易码
     * @param menuCode         菜单代码
     * @param reqBody          参数（Map）
     * @return String
     */
    private static String getParameterMap(String transServiceCode, String menuCode, Map<String, Object> reqBody) {
        Date date = new Date(System.currentTimeMillis());

        String requestDate = TimeUtils.date2String(date, "yyyyMMdd");
        String requestTime = TimeUtils.date2String(date, "hhmmss");

        StringBuilder random = new StringBuilder();
        for (int i = 0; i < KEY_RANDOM; i++) {
            Random ra = new Random();
            random.append((ra.nextInt(10) + 1));
        }
        String consumerSeqNo = "GSUTE" + requestDate + requestTime + random.toString();


        Map<String, Object> jsonHead = new HashMap<>(3);
        Map<String, Object> sysHead = new HashMap<>(30);
        //渠道号码	服务原始请求系统的系统编号C002
        sysHead.put("ConsumerId", "030107");
        //外部服务码	AFA服务码 -交易码
        sysHead.put("TransServiceCode", transServiceCode);
        //服务场景	本地服务场景
        sysHead.put("TransServiceScenc", "");
        //服务请求日期	服务请求系统的日期，格式为YYYYMMDD
        sysHead.put("RequestDate", requestDate);
        //服务请求时间	服务请求系统的时间，格式为HHMMSS
        sysHead.put("RequestTime", requestTime);
        //发起方系统流水号	服务原始请求系统的交易流水号,用来唯一标识一笔业务
        sysHead.put("ConsumerSeqNo", consumerSeqNo);
        //发起方IP	请求方IP地址
        sysHead.put("ConsumerIP", NetworkUtils.getBroadcastIpAddress());
        //目标服务器IP	服务方IP地址
        sysHead.put("ServerIP", Api.BASE_URL);
        //交易模式	1－同步处理；2－异步处理
        sysHead.put("TranMode", "1");
        //Mac值	MAC校验值(如果请求报文需要校验MAC，则需要填写这个字段)
        sysHead.put("MacValue", DeviceUtils.getMacAddress().replace(":", "").toUpperCase());


        //交易机构代码	交易机构代码
        sysHead.put("TdgBrah", SPStaticUtils.getString("TdgBrah"));
        //交易机构名称
        sysHead.put("TdgBrahName", SPStaticUtils.getString("TdgBrahName"));
        //交易柜员号	交易柜员号
        sysHead.put("TranTellerNo", SPStaticUtils.getString("TranTellerNo"));
        //交易柜员名称	柜员名称
        sysHead.put("TranTellerName", SPStaticUtils.getString("TranTellerName"));
        //设备类型
        sysHead.put("DeviceType", SPStaticUtils.getString("DeviceType"));
        //设备编码	V端分配
        sysHead.put("DeviceNum", SPStaticUtils.getString("DeviceNum"));
        //设备代码	根据机具MAC等信息计算得出
        sysHead.put("DvcNum", PosFuncs.getInstace().getTermSerial());
        //菜单代码	C端菜单ID
        sysHead.put("MenuCode", menuCode);

        jsonHead.put("SYS_HEAD", sysHead);
        Map<String, Object> appHead = new HashMap<>(30);
        //文件索引号
        appHead.put("MMDATE", "");
        //视频日期
        appHead.put("MMID", "");
        //视频ID
        appHead.put("FILEINDXNO", "");
        //呼入渠道号
        appHead.put("CHANNELCODE", "");
        //附加数据域
        appHead.put("OTHERDATA", "");
        //未知（SUTE）
        appHead.put("IttrStmInd", "SUTE");
        //语言版本
        appHead.put("I18nInd", "CH");
        //坐席号
        appHead.put("AgentId", "");
        //坐席号级别
        appHead.put("AgentLevel", "");
        //授权坐席号
        appHead.put("Auth_AgentId", "");
        //IC卡号	IC卡必送
        appHead.put("CardNo", SPStaticUtils.getString("CardNo-bindNum"));
        //55域	IC卡必送
        appHead.put("Card55", SPStaticUtils.getString("Field55"));
        //电子现金余额	IC卡必送
        appHead.put("CardEcBalance", "");
        //卡序号	IC卡必送
        appHead.put("CardSeqNo", SPStaticUtils.getString("CardSeqNo"));
        //55域长度	Card55字段值得长度除以2转16进制
        appHead.put("Card55Length", "");
        //授权坐席号级别
        appHead.put("Auth_AgentLevel", "");
        jsonHead.put("APP_HEAD", appHead);
        jsonHead.put("REQ_BODY", reqBody);

        return JSON.toJSONString(jsonHead);
    }


    /**
     * 设备激活
     *
     * @param TdgBrah      机构号、网点号
     * @param OperTellerNo 操作柜员号
     * @param TellerPwd    柜员密码
     * @param DvcNum       根据机具MAC等信息计算得出（设备编号）
     * @param VrsnNum      软件版本号
     * @return String
     */
    public static String getDeviceActivation(String TdgBrah, String OperTellerNo, String TellerPwd, String DvcNum) {
        Map<String, Object> reqBody = new HashMap<>(6);
        reqBody.put("TdgBrah", TdgBrah);
        reqBody.put("OperTellerNo", OperTellerNo);
        reqBody.put("TellerPwd", EncryptUtils.encryptMD5ToString(TellerPwd).toUpperCase());
        reqBody.put("DvcNum", DvcNum);
        reqBody.put("TranTellerNo", "");
        reqBody.put("VrsnNum", "");
        return getParameterMap("pcva.device.d001.01", "", reqBody);
    }


    /**
     * 设备查询
     *
     * @return String
     */
    public static String getEquipmentInquiry() {
        return getParameter("pcva.query.q008.01");
    }

    /**
     * 获取工作秘钥
     *
     * @return String
     */
    public static String getWorkKey() {
        return getParameter("pcva.device.d006.01");
    }


    /**
     * 签到
     *
     * @param TellerNo  柜员号
     * @param TellerPwd 柜员密码
     * @param devNum
     * @return String
     */
    public static String getSignIn(String TellerNo, String TellerPwd) {
        Map<String, Object> reqBody = new HashMap<>(6);
        reqBody.put("TellerNo", TellerNo);
        reqBody.put("TellerPwd", EncryptUtils.encryptMD5ToString(TellerPwd).toUpperCase());
        reqBody.put("LoginType", "1");
        reqBody.put("DvcNum", SPStaticUtils.getString("DeviceNum"));
        reqBody.put("FingerData", "");
        reqBody.put("type", "1");
        return getParameterMap("pcva.device.d003.01", "", reqBody);
    }


    /**
     * 验证是否为本行卡
     *
     * @param AcctNo 账号
     * @return String
     */
    public static String getCheckingThisBank(String AcctNo) {
        Map<String, Object> reqBody = new HashMap<>(1);
        reqBody.put("AcctNo", AcctNo);
        reqBody.put("SubAcctNo", "");
        reqBody.put("PinBlock", "");
        return getParameterMap("pcva.trade.b071.01", "", reqBody);
    }

    /**
     * 银行卡信息查询
     *
     * @param AcctNo   账号
     * @param PinBlock 账户密码
     * @return String
     */
    public static String getQueryBankCardInfo(String AcctNo) {
        Map<String, Object> reqBody = new HashMap<>(3);
        reqBody.put("AcctNo", AcctNo);
        return getParameterMap("pcva.trade.b031.01", "", reqBody);
    }


    /**
     * 账户密码验证
     *
     * @param AcctNo   账号
     * @param PinBlock 账户密码
     * @return String
     */
    public static String getAccountPwdVerification(String AcctNo, String PinBlock) {
        Map<String, Object> reqBody = new HashMap<>(3);
        reqBody.put("AcctNo", AcctNo);
        reqBody.put("PinBlock", PinBlock);
        return getParameterMap("pcva.trade.b029.01", "", reqBody);
    }

    /**
     * 黑名单校验
     *
     * @param AcctNo     账号
     * @param PayActName 账户名称
     * @return String String
     */
    public static String getCheckingBankCardBlacklist(String PayActNo, String PayActName) {
        Map<String, Object> reqBody = new HashMap<>(2);
        reqBody.put("PayActNo", PayActNo);
        reqBody.put("PayActName", PayActName);
        return getParameterMap("pcva.trade.b072.01", "", reqBody);
    }


    /**
     * 账户限额及交易次数查询
     *
     * @param AcctNo 账号
     * @return String String
     */
    public static String getQueryAccountNorm(String AcctNo) {
        Map<String, Object> reqBody = new HashMap<>(1);
        reqBody.put("AcctNo", AcctNo);
        return getParameterMap("pcva.trade.p002.01", "", reqBody);
    }


    /**
     * 行名行号查询
     *
     * @param AcctNo 银行名称
     * @return String String
     */
    public static String getQueryAliasBankCardInfo(String BankName) {
        Map<String, Object> reqBody = new HashMap<>(1);
        reqBody.put("BankName", BankName);
        return getParameterMap("pcva.trade.b075.01", "", reqBody);
    }


    /**
     * 手续费查询
     *
     * @param PayAcctNo   付款账号
     * @param PayBankNo   付款账号开户行
     * @param PayeeBankNo 收款行行号
     * @param PayeeAcctNo 收款账号
     * @param Amount      金额
     * @return String
     */
    public static String getQueryServiceCharge(String PayAcctNo, String PayBankNo, String PayeeBankNo, String PayeeAcctNo, String Amount) {
        Map<String, Object> reqBody = new HashMap<>(5);
        reqBody.put("PayAcctNo", PayAcctNo);
        reqBody.put("PayBankNo", PayBankNo);
        reqBody.put("PayeeBankNo", PayeeBankNo);
        reqBody.put("PayeeAcctNo", PayeeAcctNo);
        try {
            reqBody.put("Amount", MoneyUtil.getMoney(Amount));
        } catch (NumberFormatException numberFormatException) {
            numberFormatException.printStackTrace();
            ToastUtils.showShort(numberFormatException.getMessage());
            return null;
        }
        return getParameterMap("pcva.trade.b076.01", "", reqBody);
    }

    /**
     * 转账
     *
     * @param PayActNo     付款账号
     * @param PayActName   付款账户名称
     * @param PayeeActNo   收款账号
     * @param PayeeActName 收款账户名称
     * @param PayeeBankNo  收款行行号
     * @param PinBlock     账户密码
     * @param Amount       金额
     * @param TransferType 转账方式 1：本行 2：跨行
     * @param TradeFee     手续费
     * @return String
     */

    public static String getTransfer(String PayActNo, String PayActName,
                                     String PayeeActNo, String PayeeActName,
                                     String PayeeBankNo, String PinBlock,
                                     String Amount, String TransferType, String TradeFee, String menuCode) {
        Map<String, Object> reqBody = new HashMap<>(10);
        reqBody.put("PayActNo", PayActNo);
        reqBody.put("PayActName", PayActName);
        reqBody.put("PayeeActNo", PayeeActNo);
        reqBody.put("PayeeActName", PayeeActName);
        reqBody.put("PayeeBankNo", PayeeBankNo);
        reqBody.put("PinBlock", PinBlock);
        try {
            reqBody.put("Amount", MoneyUtil.getMoney(Amount));
        } catch (NumberFormatException numberFormatException) {
            numberFormatException.printStackTrace();
            ToastUtils.showShort(numberFormatException.getMessage());
            return null;
        }
        reqBody.put("TransferPriority", "0");
        reqBody.put("TransferType", TransferType);
        reqBody.put("TradeFee", TradeFee);
        return getParameterMap("pcva.trade.b052.01", menuCode, reqBody);
    }


    /**
     * 联网核查
     *
     * @param id   被核对人身份证号码
     * @param name 被核对人姓名
     * @return String
     */
    public static String getNetworkVerification(String id, String name) {
        Map<String, Object> reqBody = new HashMap<>(2);
        reqBody.put("id", id);
        reqBody.put("name", name);
        return getParameterMap("pcva.trade.b087.01", "", reqBody);
    }

    /**
     * 合成电子印章
     *
     * @param type 电子印章类型
     * @param name 被核对人姓名
     * @return String
     */
    public static String getElectronicSeal(String type) {
        Map<String, Object> reqBody = new HashMap<>(1);
        reqBody.put("type", type);
        return getParameterMap("pcva.trade.b091.01", "", reqBody);
    }

    /**
     * 利率查询
     *
     * @return String
     */
    public static String getInterestRateInquiry() {
        return getParameter("pcva.trade.b070.01");
    }


    /**
     * 客户账户信息查询
     *
     * @param IDType 身份证件类型
     * @param IDNo   身份证件号码
     * @param IDName 证件姓名
     * @param AcctNo 账号
     * @return String
     */
    public static String getCustomerAccountInformationQuery(String IDType, String IDNo, String IDName, String AcctNo) {
        Map<String, Object> reqBody = new HashMap<>(4);
        reqBody.put("IDType", IDType);
        reqBody.put("IDNo", IDNo);
        reqBody.put("IDName", IDName);
        reqBody.put("AcctNo", AcctNo);
        return getParameterMap("pcva.trade.b030.01", "", reqBody);
    }


    /**
     * 银行卡挂失
     *
     * @param AcctNo      账号
     * @param VoucherType 凭证类型
     * @param VoucherNo   凭证号码
     * @param PinBlock    账户密码
     * @param IDType      身份证件类型
     * @param IDNo        身份证件号码
     * @return String
     */
    public static String getLostBankCard(String AcctNo, String VoucherType, String VoucherNo, String PinBlock, String IDType, String IDNo) {
        Map<String, Object> reqBody = new HashMap<>(6);
        reqBody.put("AcctNo", AcctNo);
        reqBody.put("VoucherType", VoucherType);
        reqBody.put("VoucherNo", VoucherNo);
        reqBody.put("IDType", IDType);
        reqBody.put("PinBlock", PinBlock);
        reqBody.put("IDNo", IDNo);
        return getParameterMap("pcva.trade.b060.01", "", reqBody);
    }


    /**
     * 密码修改
     *
     * @param CardNo       卡号
     * @param OrigPinBlock 账户原密码
     * @param PinBlock     账户密码
     * @param CustName     客户名称
     * @param CustNo       客户号
     * @param IDType       身份证件类型
     * @param IDNo         身份证件号码
     * @param SecondTrack  二磁道
     * @return String
     */
    public static String getChangePassword(String CardNo, String OrigPinBlock, String PinBlock, String CustName, String CustNo, String IDType, String IDNo, String SecondTrack) {
        Map<String, Object> reqBody = new HashMap<>(8);
        reqBody.put("CardNo", CardNo);
        reqBody.put("OrigPinBlock", OrigPinBlock);
        reqBody.put("PinBlock", PinBlock);
        reqBody.put("CustName", CustName);
        reqBody.put("CustNo", CustNo);
        reqBody.put("IDType", IDType);
        reqBody.put("IDNo", IDNo);
        reqBody.put("SecondTrack", SecondTrack);
        return getParameterMap("pcva.trade.b036.01", "", reqBody);
    }


    /**
     * 子账户信息查询
     *
     * @param AcctNo      账号
     * @param PinBlock    密码
     * @param FUNC        功能代码
     * @param ProductCode 综合理财帐户编号(PDT)
     * @return String
     */

    public static String getSubAccountInformationQuery(String AcctNo, String PinBlock, String FUNC, String ProductCode) {
        Map<String, Object> reqBody = new HashMap<>(8);
        reqBody.put("AcctNo", AcctNo);
        reqBody.put("FUNC", FUNC);
        reqBody.put("PinBlock", PinBlock);
        reqBody.put("ProductCode", ProductCode);
        return getParameterMap("pcva.trade.b074.01", "", reqBody);
    }


    /**
     * 账户活期明细查询
     *
     * @param AcctNo   账号
     * @param PinBlock 密码
     * @param FUNC     功能代码
     * @param STRDATE  开始日期
     * @param ENDDATE  截止日期
     * @return String
     */
    public static String getAccountCurrentDetailsInquiry(String AcctNo, String PinBlock, String FUNC, String STRDATE, String ENDDATE) {
        Map<String, Object> reqBody = new HashMap<>(5);
        reqBody.put("AcctNo", AcctNo);
        reqBody.put("FUNC", FUNC);
        reqBody.put("PinBlock", PinBlock);
        reqBody.put("STRDATE", STRDATE);
        reqBody.put("ENDDATE", ENDDATE);
        return getParameterMap("pcva.trade.b073.01", "", reqBody);
    }


    /**
     * 账户定期明细查询
     *
     * @param AcctNo      账号
     * @param PinBlock    密码
     * @param FUNC        功能代码
     * @param STRDATE     开始日期
     * @param ENDDATE     截止日期
     * @param PSBK_SQ_NO  本册笔号
     * @param SecondTrack 二磁道
     * @return String
     */
    public static String getAccountDetailsInquiry(String AcctNo, String PinBlock, String FUNC, String STRDATE, String ENDDATE, String PSBK_SQ_NO, String SecondTrack) {
        Map<String, Object> reqBody = new HashMap<>(7);
        reqBody.put("AcctNo", AcctNo);
        reqBody.put("FUNC", FUNC);
        reqBody.put("PinBlock", PinBlock);
        reqBody.put("STRDATE", STRDATE);
        reqBody.put("ENDDATE", ENDDATE);
        reqBody.put("PSBK_SQ_NO", PSBK_SQ_NO);
        reqBody.put("SecondTrack", SecondTrack);
        return getParameterMap("pcva.trade.b080.01", "", reqBody);
    }


    /**
     * 本代他余额查询
     *
     * @param AcctNo         主账号
     * @param TwoTrack       第二磁道数据
     * @param ThreeTrack     第三磁道数据
     * @param PinBlock       自定义域
     * @param PersonFlg      个人标识码数据
     * @param ProxyBranchFlg 代理机构标识码
     * @param ServiceCode    服务点输入方式码
     * @param SignAgreeNum   签约协议号
     * @param CarNum         发起方卡号
     * @return String
     */
    public static String getCurrentBalanceCheck(String AcctNo, String TwoTrack,
                                                String ThreeTrack, String PinBlock,
                                                String PersonFlg, String ProxyBranchFlg,
                                                String ServiceCode, String SignAgreeNum,
                                                String CarNum) {
        Map<String, Object> reqBody = new HashMap<>(9);
        reqBody.put("AcctNo", AcctNo);
        reqBody.put("TwoTrack", TwoTrack);
        reqBody.put("ThreeTrack", ThreeTrack);
        reqBody.put("PinBlock", PinBlock);
        reqBody.put("PersonFlg", PersonFlg);
        reqBody.put("ProxyBranchFlg", ProxyBranchFlg);
        reqBody.put("ServiceCode", ServiceCode);
        reqBody.put("SignAgreeNum", SignAgreeNum);
        reqBody.put("CarNum", CarNum);
        return getParameterMap("pcva.trade.b096.01", "", reqBody);
    }


    /**
     * 他行卡转入
     *
     * @param PayeeName        收款方名称
     * @param PayerName        付款方名称
     * @param PosEntryModeCode 服务点输入方式码
     * @param PayeeAcctNo      转入卡号
     * @param PinBlock         密码密文
     * @param TransCurrCode    交易货币代码
     * @param Amount           交易金额
     * @param ThreeTrack       第三磁道数据
     * @param SecondTrack      第二磁道数据
     * @param AcctNo           转出卡号
     * @param ATMSign          ATM标志
     * @return String
     */
    public static String getTransferOfOtherCards(String PayeeName, String PayerName,
                                                 String PosEntryModeCode, String PayeeAcctNo,
                                                 String PinBlock, String TransCurrCode,
                                                 String Amount, String ThreeTrack,
                                                 String SecondTrack, String AcctNo, String ATMSign) {
        Map<String, Object> reqBody = new HashMap<>(11);
        reqBody.put("PayeeName", PayeeName);
        reqBody.put("PayerName", PayerName);
        reqBody.put("PosEntryModeCode", PosEntryModeCode);
        reqBody.put("PayeeAcctNo", PayeeAcctNo);
        reqBody.put("PinBlock", PinBlock);
        reqBody.put("TransCurrCode", TransCurrCode);
        try {
            reqBody.put("Amount", MoneyUtil.getMoney(Amount));
        } catch (NumberFormatException numberFormatException) {
            numberFormatException.printStackTrace();
            ToastUtils.showShort(numberFormatException.getMessage());
            return null;
        }
        reqBody.put("ThreeTrack", ThreeTrack);
        reqBody.put("SecondTrack", SecondTrack);
        reqBody.put("AcctNo", AcctNo);
        reqBody.put("ATMSign", ATMSign);
        return getParameterMap("pcva.trade.b097.01", "", reqBody);
    }


    /**
     * 个人理财明细查询
     *
     * @param AcctNo    账号
     * @param PinBlock  密码
     * @param StartDate 开始时间 YYYYMMDD
     * @param ENDDate   结束日期 YYYYMMDD
     * @return String
     */
    public static String getPersonalFinancialDetailsInquiry(String AcctNo, String PinBlock,
                                                            String StartDate, String ENDDate) {
        Map<String, Object> reqBody = new HashMap<>(4);
        reqBody.put("AcctNo", AcctNo);
        reqBody.put("PinBlock", PinBlock);
        reqBody.put("StartDate", StartDate);
        reqBody.put("ENDDate", ENDDate);
        return getParameterMap("pcva.trade.b086.01", "", reqBody);
    }


    /**
     * 电子现金圈存
     *
     * @param FUNC           功能号
     * @param AcctNo         卡号
     * @param ExpdDate       有效期限
     * @param CURR_COD       币别
     * @param SecondMtCon    二磁道
     * @param PinBlock       密码
     * @param Amount         交易金额
     * @param ShopType       商户类别
     * @param ATMNo          ATM编号
     * @param ATMSeqNo       ATM交易序号
     * @param TradeCheckType 交易验证类型 送001
     * @return String
     */
    public static String getElectronicCashTransfer(String FUNC, String AcctNo,
                                                   String ExpdDate, String CURR_COD,
                                                   String SecondMtCon, String PinBlock,
                                                   String Amount, String ShopType,
                                                   String ATMNo, String ATMSeqNo, String TradeCheckType) {
        Map<String, Object> reqBody = new HashMap<>(11);
        reqBody.put("FUNC", FUNC);
        reqBody.put("AcctNo", AcctNo);
        reqBody.put("ExpdDate", ExpdDate);
        reqBody.put("CURR_COD", CURR_COD);
        reqBody.put("SecondMtCon", SecondMtCon);
        reqBody.put("PinBlock", PinBlock);
        try {
            reqBody.put("Amount", MoneyUtil.getMoney(Amount));
        } catch (NumberFormatException numberFormatException) {
            numberFormatException.printStackTrace();
            ToastUtils.showShort(numberFormatException.getMessage());
            return null;
        }
        reqBody.put("ShopType", ShopType);
        reqBody.put("ATMNo", ATMNo);
        reqBody.put("ATMSeqNo", ATMSeqNo);
        reqBody.put("TradeCheckType", TradeCheckType);
        return getParameterMap("pcva.trade.b084.01", "", reqBody);
    }


    /**
     * 脚本结果通知
     *
     * @param AcctNo        卡号
     * @param OldTraDate    原交易日期
     * @param OldService_id 取原交易流水号
     * @param Scr_result    脚本结果 如果长度大于6，截取6之后的信息，如果不大于6，截取最后一位
     * @param SeqNo         电子现金圈存交易C端流水号
     * @return String
     */
    public static String getScriptResultNotification(String AcctNo, String OldTraDate,
                                                     String OldService_id, String Scr_result,
                                                     String SeqNo) {
        Map<String, Object> reqBody = new HashMap<>(5);
        reqBody.put("AcctNo", AcctNo);
        reqBody.put("OldTraDate", OldTraDate);
        reqBody.put("OldService_id", OldService_id);
        reqBody.put("Scr_result", Scr_result);
        reqBody.put("SeqNo", SeqNo);
        return getParameterMap("pcva.trade.b085.01", "", reqBody);
    }


    /**
     * 定转活
     *
     * @param AcctNo      账号
     * @param Amount      金额
     * @param PinBlock    账户密码
     * @param SecondTrack 二磁道
     * @param DrawCode    支取帐户编号
     * @param Draw_NO     支取理财帐户笔号
     * @param CertType    证件种类
     * @param IDNO        证件号码
     * @param CustName    客户名称
     * @return String
     */
    public static String getFixedTurn(String AcctNo, String Amount,
                                      String PinBlock, String SecondTrack,
                                      String DrawCode, String Draw_NO,
                                      String CertType, String IDNO, String CustName) {
        Map<String, Object> reqBody = new HashMap<>(5);
        reqBody.put("AcctNo", AcctNo);
        try {
            reqBody.put("Amount", MoneyUtil.getMoney(Amount));
        } catch (NumberFormatException numberFormatException) {
            numberFormatException.printStackTrace();
            ToastUtils.showShort(numberFormatException.getMessage());
            return null;
        }
        reqBody.put("PinBlock", PinBlock);
        reqBody.put("SecondTrack", SecondTrack);
        reqBody.put("DrawCode", DrawCode);
        reqBody.put("Draw_NO", Draw_NO);
        reqBody.put("CertType", CertType);
        reqBody.put("IDNO", IDNO);
        reqBody.put("CustName", CustName);
        return getParameterMap("pcva.trade.b065.01", "", reqBody);
    }


    /**
     * 产品参数查询
     *
     * @param ProductCode 产品代码
     * @param Amount      开户金额
     * @return String
     */
    public static String getFixedTurn(String ProductCode, String Amount) {
        Map<String, Object> reqBody = new HashMap<>(5);
        reqBody.put("ProductCode", ProductCode);
        try {
            reqBody.put("Amount", MoneyUtil.getMoney(Amount));
        } catch (NumberFormatException numberFormatException) {
            numberFormatException.printStackTrace();
            ToastUtils.showShort(numberFormatException.getMessage());
            return null;
        }
        return getParameterMap("pcva.trade.b092.01", "", reqBody);
    }

    /**
     * 活期转定期
     *
     * @param TradeType          交易类别
     * @param AcctNo             卡号
     * @param PinBlock           密码
     * @param DrwKind            支取类别
     * @param Amount             支取金额
     * @param DepositTerm        存期
     * @param DepositType        存款种类
     * @param DepositProductCode 存入帐户编号
     * @param SecondTrack        二磁道
     * @param DrawCode           支取帐户编号
     * @param ProductCode        产品编号
     * @param MNG_FLG            理财标志
     * @param TFT_EMP_NO         员工号
     * @param TFT_TD_INT_ACCT_NO 收息账号
     * @return String
     */
    public static String getCurrentTransfer(String TradeType, String AcctNo,
                                            String PinBlock, String DrwKind,
                                            String Amount, String DepositTerm,
                                            String DepositType, String DepositProductCode,
                                            String SecondTrack, String DrawCode,
                                            String ProductCode, String MNG_FLG,
                                            String TFT_EMP_NO, String TFT_TD_INT_ACCT_NO) {
        Map<String, Object> reqBody = new HashMap<>(13);
        reqBody.put("TradeType", TradeType);
        reqBody.put("AcctNo", AcctNo);
        reqBody.put("PinBlock", PinBlock);
        reqBody.put("DrwKind", DrwKind);
        try {
            reqBody.put("Amount", MoneyUtil.getMoney(Amount));
        } catch (NumberFormatException numberFormatException) {
            numberFormatException.printStackTrace();
            ToastUtils.showShort(numberFormatException.getMessage());
            return null;
        }
        reqBody.put("DepositTerm", DepositTerm);
        reqBody.put("DepositType", DepositType);
        reqBody.put("DepositProductCode", DepositProductCode);
        reqBody.put("SecondTrack", SecondTrack);
        reqBody.put("DrawCode", DrawCode);
        reqBody.put("ProductCode", ProductCode);
        reqBody.put("MNG_FLG", MNG_FLG);
        reqBody.put("TFT_EMP_NO", TFT_EMP_NO);
        reqBody.put("TFT_TD_INT_ACCT_NO", TFT_TD_INT_ACCT_NO);
        return getParameterMap("pcva.trade.b082.01", "", reqBody);
    }


    /**
     * 周周赢业务，定活自转业务签约查询
     *
     * @param AcctNo 银行卡号
     * @return String
     */
    public static String getSigningInquiry(String AcctNo) {
        Map<String, Object> reqBody = new HashMap<>(1);
        reqBody.put("AcctNo", AcctNo);
        return getParameterMap("pcva.trade.b077.01", "", reqBody);
    }

    /**
     * 周周赢业务，定活自转业务详情查询
     *
     * @param ProductCode 产品代码
     * @return String
     */
    public static String getSigningDetailsInquiry(String ProductCode) {
        Map<String, Object> reqBody = new HashMap<>(1);
        reqBody.put("ProductCode", ProductCode);
        return getParameterMap("pcva.trade.b083.01", "", reqBody);
    }


    /**
     * 周周赢业务，定活自转业务签约
     *
     * @param AcctNo       账号
     * @param ProductCode  产品代码
     * @param TransAmt     自动转存基数
     * @param FdepAmt      起存金额
     * @param BalanceLimit 余额下限
     * @param PinBlock     密码
     * @return String
     */
    public static String getSigningBusinessContract(String AcctNo, String ProductCode,
                                                    String TransAmt, String FdepAmt,
                                                    String BalanceLimit, String PinBlock) {
        Map<String, Object> reqBody = new HashMap<>(6);
        reqBody.put("AcctNo", AcctNo);
        reqBody.put("ProductCode", ProductCode);
        try {
            reqBody.put("TransAmt", MoneyUtil.getMoney(TransAmt));
            reqBody.put("FdepAmt", MoneyUtil.getMoney(FdepAmt));
            reqBody.put("BalanceLimit", MoneyUtil.getMoney(BalanceLimit));
        } catch (NumberFormatException numberFormatException) {
            numberFormatException.printStackTrace();
            ToastUtils.showShort(numberFormatException.getMessage());
            return null;
        }
        reqBody.put("PinBlock", PinBlock);
        return getParameterMap("pcva.trade.b078.01", "", reqBody);
    }


    /**
     * 周周赢业务，定活自转业务解约
     *
     * @param AcctNo   账号
     * @param PinBlock 密码
     * @return String
     */
    public static String getSigningBusinessTermination(String AcctNo, String PinBlock) {
        Map<String, Object> reqBody = new HashMap<>(6);
        reqBody.put("AcctNo", AcctNo);
        reqBody.put("PinBlock", PinBlock);
        return getParameterMap("pcva.trade.b079.01", "", reqBody);
    }

    /**
     * 主秘钥计算
     *
     * @param key1 分量秘钥1
     * @param key2 分量秘钥2
     * @return 主秘钥
     */
    public static String getPrimarySecretKey(String key1, String key2) {
        StringBuilder secretKey = new StringBuilder();
        if (!TextUtils.isEmpty(key1) && !TextUtils.isEmpty(key2)) {
            for (int i = 0; i < 32; i++) {
                secretKey.append(Integer.toHexString(Integer.valueOf(key1.substring(i, i + 1), 16) ^
                        Integer.valueOf(key2.substring(i, i + 1), 16)).toUpperCase());
            }
            return secretKey.toString();
        }
        return null;
    }

    /**
     * 加密获得密码密文
     * <p>
     * 账号密码处理 获取pinblock
     *
     * @param password
     * @param account
     * @return
     */
    public static String getResult(String password, String account) {
        password = ("" + (password.length() + 100)).substring(1, 3) + password;
        password = (password + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF").substring(0, 32);

        account = account.substring(0, account.length() - 1);
        account = account.substring(account.length() - 12, account.length());
        account = ("00000000000000000000000000000000" + account);
        account = account.substring(account.length() - 32, account.length());

        String result = "";
        for (int i = 0; i < 32; i++) {
            String x1 = password.substring(i, i + 1);
            String x2 = account.substring(i, i + 1);
            Integer x = Integer.valueOf(x1, 16) ^ Integer.valueOf(x2, 16);
            result += Integer.toHexString(x).toUpperCase();
        }
        return SM4.main(result);
    }

    /**
     * 更新管理员密码   具体传参数 看你那边 pcva.device.d004.01是正确的
     *
     * @return
     */
    public static String changeOperationPw() {
        Map<String, Object> reqBody = new HashMap<>(6);
//        reqBody.put("AcctNo", AcctNo);
//        reqBody.put("PinBlock", PinBlock);
        return getParameterMap("pcva.device.d004.01", "", reqBody);
    }

    /**
     * 修改主密钥
     * 传参自己写一下
     *
     * @return
     */
    public static String changeMainKey() {
        Map<String, Object> reqBody = new HashMap<>(6);
//        reqBody.put("AcctNo", AcctNo);
//        reqBody.put("PinBlock", PinBlock);
        return getParameterMap("", "", reqBody);
    }

    /**
     * 本机交易汇总查询
     * 传参自己加一下
     *
     * @return
     */
    public static String getStatistics() {
        Map<String, Object> reqBody = new HashMap<>(6);
//        reqBody.put("AcctNo", AcctNo);
//        reqBody.put("PinBlock", PinBlock);
        return getParameterMap("", "", reqBody);
    }

    /**
     * 本机交易查询
     * * 传参自己加一下
     *
     * @return
     */
    public static String gettransactionqQuery() {
        Map<String, Object> reqBody = new HashMap<>(6);
//        reqBody.put("AcctNo", AcctNo);
//        reqBody.put("PinBlock", PinBlock);
        return getParameterMap("", "", reqBody);
    }

    /**
     * 通用方法
     *
     * @param transServiceCode 交易码
     * @return String
     */
    private static String getParameter(String transServiceCode) {
        return getParameterMap(transServiceCode, "", new HashMap<>(0));
    }
}